﻿using TK.Common.Logger;

namespace TK.Common.Http
{
    /// <summary>
    /// HttpClient日志记录
    /// </summary>
    public class HttpClientTraceDelegatingHandler : DelegatingHandler
    {
        private readonly ILogger<HttpClientTraceDelegatingHandler> _logger;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly string _traceUrls;

        /// <summary>
        /// ctor
        /// </summary>
        public HttpClientTraceDelegatingHandler(
            IConfiguration configuration,
            ILogger<HttpClientTraceDelegatingHandler> logger,
            IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _traceUrls = configuration["HttpClient.TraceUrls"];
            _httpContextAccessor = httpContextAccessor;
        }

        /// <summary>
        /// SendAsync
        /// </summary>
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var traceId = _httpContextAccessor.HttpContext?.TraceIdentifier;
            if (!string.IsNullOrWhiteSpace(traceId))
            {
                request.Headers.Add(RequestLoggingOptions.TraceKey, traceId);
            }

            var response = await base.SendAsync(request, cancellationToken);
            //记录请求日志
            await TraceRequestInfoAsync(request, response);

            return response;
        }

        /// <summary>
        /// Send
        /// </summary>
        protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return SendAsync(request, cancellationToken).Result;
        }

        #region private methods

        private async Task TraceRequestInfoAsync(HttpRequestMessage request, HttpResponseMessage response)
        {
            var requestUrl = request.RequestUri.ToString();
            if (IsNeedTrace(requestUrl))
            {
                var requestTxt = string.Empty;
                if (request.Content != null && !(request.Content is MultipartFormDataContent))
                {
                    requestTxt = await request.Content.ReadAsStringAsync();
                }

                var responseTxt = string.Empty;
                if (response.Content != null)
                {
                    responseTxt = await response.Content.ReadAsStringAsync();
                }

                _logger.LogError($"HttpClient|Url:{requestUrl}|Req:{requestTxt}|Code:{response.StatusCode}|Rep:{responseTxt}");
            }
        }

        /// <summary>
        /// 需要跟踪的url,未设置默认所有
        /// </summary>
        private bool IsNeedTrace(string url)
        {
            if (!string.IsNullOrWhiteSpace(_traceUrls))
            {
                var traceUrlList = _traceUrls.Split(";", StringSplitOptions.RemoveEmptyEntries).ToList();
                return traceUrlList.Any(p => url.Contains(p));
            }

            return true;
        }

        #endregion
    }
}
